精通Linux系列二:Linux的文件系统
点击关注公众号,AI,编程干货及时送达
要利用任何Linux系统,你需要对Linux的文件和目录(也称为文件夹)有所了解。在一个“窗口和图标”的系统中,屏幕上明显显示出文件和目录。但在像Linux shell这样的命令行系统中,同样的文件和目录仍然存在,但并不是一直可见,所以有时你需要记住你正在哪个目录中,以及它如何与其他目录相关联。你将使用像cd
和pwd
这样的shell命令在目录之间“移动”并跟踪你的位置。
让我们来看看一些术语。正如我们所说,Linux文件被收集到目录中。目录形成一个层级或树状结构,如[图3]所示:一个目录可能包含其他目录,这些目录被称为子目录,子目录本身可能包含其他文件和子目录,以此类推,无穷无尽。最顶层的目录被称为根目录,由斜杠(/)表示。
图3. Linux文件系统(部分)。根目录位于顶部。“dan”目录的绝对路径是/home/dan。
我们用一种叫做路径的“名称和斜杠”语法来引用文件和目录。例如,这个路径:
/one/two/three/four
指的是根目录 /,其中包含一个名为one的目录,one包含一个名为two的目录,two包含一个名为three的目录,three包含一个最终的文件或目录,名为four。任何以斜杠开头的路径,从根目录一直下来的,都被称为绝对路径。
路径不必是绝对的:它们可以相对于根目录以外的某个目录。在[图3]中,有两个不同的目录都叫做bin,其绝对路径是*/bin和/usr/bin。如果我们只是提到“bin目录”,并不清楚我们是指哪一个(并且可能还有许多其他的bin目录)。更多的上下文是必要的。任何时候你引用一个不以斜杠开头的路径,比如bin*,它就被称为相对路径。
要理解相对路径,你需要知道你在Linux文件系统中的“位置”。这个位置被称为你的当前工作目录(或者就叫“当前目录”)。每个shell都有一个当前工作目录,当你在该shell中运行命令时,它们相对于那个目录进行操作。例如,如果你的shell在*/usr目录中,你运行一个引用相对路径bin的命令,你实际上是在引用/usr/bin。一般来说,如果你的当前目录是/one/two/three,一个相对路径a/b/c会指向绝对路径/one/two/three/a/b/c*。
两个特殊的相对路径分别被记作 .(一个句点)和..(两个连续的句点)。前者表示你的当前目录,后者表示你的父目录,即上一级。所以如果你的当前目录是*/one/two/three,那么.就表示这个目录,..就表示/one/two*。
你使用cd
命令将你的shell从一个目录“移动”到另一个目录:
→ cd /usr/local/bin
更准确地说,这个命令将你的shell的当前工作目录改为*/usr/local/bin*。这是一个绝对变化(因为目录以“/”开始)。假设你将书中的示例目录安装在了你的主目录,你可以随时通过运行以下命令跳转到它:
→ cd ~/linuxpocketguide
(其中的波浪线是我们将在下一节介绍的一个缩写)。你也可以使用cd
进行相对移动:
→ cd d 进入子目录d
→ cd ../mydir 上升到我的父目录,然后进入目录mydir
文件和目录的名称可以包含你预期的大多数字符:大写和小写字母,数字,句点,破折号,下划线和大多数符号(但不能包含“/”,因为它是用来分隔目录的)。然而,为了实际使用,避免使用空格、星号、美元符号、括号和其他对shell具有特殊含义的字符。否则,你需要一直引用或转义这些字符。(参见[“引用”])。
Home Directories
用户的个人文件通常位于*/home目录(对于普通用户)或者/root目录(对于超级用户)。你的家目录通常是/home/<你的用户名>*(例如 /home/smith, /home/jones 等)。有几种方法可以定位或者引用你的家目录:
•
cd
如果没有参数,
cd
命令将你(即设置shell的工作目录)返回到你的家目录。•
HOME
变量环境变量
HOME
(参见[“Shell 变量”])包含你的家目录的名称:→ **
echo $HOME** echo命令打印出它的参数 /home/smith
•
~
如果用于替代目录,一个单独的波浪线会被shell扩展为你家目录的名称:
→
echo/home/smith
当波浪线后面跟着一个斜线,路径相对于
HOME
:→ **
echo ~/linuxpocketguide** /home/smith/linuxpocketguide
当波浪线后面跟着一个用户名(例如 *fred*),shell会将此字符串扩展为用户的家目录:
→ **
cd ~fred** 如果你的系统上有一个用户“fred” → **
pwd
** 打印工作目录的命令 /home/fred
系统目录(System Directories)
一个典型的Linux系统有成千上万的系统目录。这些目录包含操作系统文件、应用程序、文档,以及几乎所有除了个人用户文件的东西(这些文件通常存在于*/home*目录中)。
除非你是一个系统管理员,你很少会访问大多数系统目录——但是有了一点知识,你就可以理解或猜测它们的用途。他们的名称通常包含三个部分,如[图 4]所示。
图 4. 目录的范围、类别和应用
目录路径部分1:类别(Category)
类别告诉你一个目录中找到的文件的类型。例如,如果类别是bin,你可以合理地确定该目录包含程序。一些常见的类别如下:
程序类别(Categories for programs) | |
bin | 程序(通常是二进制文件) |
sbin | 程序(通常是二进制文件),主要供超级用户运行 |
lib | 程序使用的代码库 |
文档类别(Categories for documentation) | |
doc | 文档 |
info | Emacs内置帮助系统的文档文件 |
man | 由man 程序显示的文档文件(手册页);这些文件通常被压缩,并带有供man 解释的排版命令 |
share | 程序特定文件,如示例和安装说明 |
配置类别(Categories for configuration) | |
etc | 系统的配置文件(以及其他杂项) |
init.d | 启动Linux的配置文件 |
rc.d | 启动Linux的配置文件;还包括rc1.d, rc2.d,等等... |
编程类别(Categories for programming) | |
include | 编程的头文件 |
src | 程序的源代码 |
网页文件类别(Categories for web files) | |
cgi-bin | 在网页上运行的脚本/程序 |
html | 网页 |
public_html | 网页,通常位于用户的家目录中 |
www | 网页 |
显示类别(Categories for display) | |
fonts | 字体(惊喜!) |
X11 | X窗口系统文件 |
硬件类别(Categories for hardware) | |
dev | 用于与磁盘和其他硬件接口的设备文件 |
media | 挂载点:提供对磁盘访问的目录 |
mnt | 挂载点:提供对磁盘访问的目录 |
运行时文件类别(Categories for runtime files) | |
var | 与此计算机特定的文件,创建和更新时计算机正在运行 |
lock | 锁文件,由程序创建以表示:“我正在运行”;锁文件的存在可能阻止另一个程序,或者同一个程序的另一个实例,运行或执行操作 |
log | 记录重要系统事件的日志文件,包含错误、警告和信息消息 |
收入邮件的邮箱 | |
run | PID文件,包含正在运行的进程的ID;这些文件通常用于追踪或杀死特定的进程 |
spool | 队列中或传输中的文件,如发出的邮件,打印任务和计划任务 |
tmp | 供程序和/或人员使用的临时存储 |
proc | 操作系统状态:参见[“操作系统目录(Operating System Directories)”] |
目录路径的第二部分:范围
目录路径的范围描述了整个目录层次结构的高级目的。一些常见的包括:
/ | 伴随Linux一起提供的系统文件(root) |
/usr | 更多伴随Linux一起提供的系统文件(读作“用户”) |
/usr/local | “本地”开发的系统文件,要么为你的组织,要么为你的个人计算机 |
/usr/games | 游戏(没错!) |
因此,对于类似lib(库)这样的类别,你的Linux系统可能有*/lib,/usr/lib,/usr/local/lib和/usr/games/lib*这样的目录。
在实践中,*/和/usr之间并没有明显的区别,但/被认为是“更低级别”的,更接近操作系统。因此,/bin比/usr/bin包含更基础的程序,比如ls
和cat
,/lib比/usr/lib包含更基础的库,等等。/usr/local/bin*包含你的发行版中未包含的程序。这些并非严格的规则,而是典型的情况。
目录路径的第三部分:应用
目录路径的应用部分(如果存在)通常是程序的名称。在范围和类别之后(比如说,*/usr/local/doc),一个程序可能有它需要的文件包含在自己的子目录中(比如说,/usr/local/doc/myprogram*)。
操作系统目录
有些目录支持Linux内核,这是Linux操作系统的最底层部分:
• /boot用于启动系统的文件。这是内核的存放位置,通常命名为*/boot/vmlinuz*或类似。
• /lost+found由磁盘恢复工具挽救的损坏文件。
• /proc描述当前正在运行的进程;用于高级用户。
/proc中的文件提供了正在运行的内核的视图,并且具有特殊的属性。它们始终看起来是零大小,只读,且日期为当前:
→ ls -lG /proc/version
-r--r--r-- 1 root 0 Oct 3 22:55 /proc/version
然而,它们的内容神奇地包含了关于Linux内核的信息:
→ cat /proc/version
Linux version 2.6.32-71.el6.i686 ...
/proc中的文件大多被程序使用,但随意探索也无妨。以下是一些例子:
/proc/ioports | 关于你的计算机的输入/输出硬件的列表。 |
/proc/cpuinfo | 关于你的计算机的处理器的信息。 |
/proc/version | 操作系统版本。uname 命令会打印相同的信息。 |
/proc/uptime | 系统运行时间(即,自系统最后一次启动以来所经过的秒数)。运行uptime 命令以获得更易读的结果。 |
*/proc/*nnn | 关于ID为nnn的Linux进程的信息,其中nnn是一个正整数。 |
/proc/self | 关于你正在运行的当前进程的信息;一个指向*/proc/*nnn文件的符号链接,自动更新。尝试连续运行几次:→ ** ls -l /proc/self** 你会看到*/proc/self*指向的地方在变化。 |
文件保护
Linux系统可能有许多具有登录账户的用户。为了维护隐私和安全性,大多数用户只能访问系统上的部分文件,而不是全部。这种访问控制体现在两个问题上:
• 谁有权限?每个文件和目录都有一个拥有者,拥有者有权对其进行任何操作。通常,创建文件的用户就是其所有者,但超级用户可以更改所有权。此外,预定义的用户组可能有权访问文件。用户组由系统管理员定义,详见[“群组管理”]。最后,文件或目录可以开放给系统上所有具有登录账户的用户。你也会看到这组用户被称为全世界或者简称其他。
• 授予何种权限?文件所有者、用户组和全世界可能都有权限读取、写入(修改)和执行(运行)特定的文件。权限也扩展到目录,用户可以读取(访问目录内的文件)、写入(在目录内创建和删除文件)和执行(用
cd
进入目录)。
要查看名为myfile的文件的所有权和权限,运行:
→ ls -l myfile
-rw-r--r-- 1 smith smith 1168 Oct 28 2015 myfile
要查看名为mydir的目录的所有权和权限,添加-d
选项:
→ ls -ld mydir
drwxr-x``` 3 smith smith 4096 Jan 08 15:02 mydir
在输出中,文件权限是最左边的10个字符,包含r
(读取),w
(写入),x
(执行),其他字母和短划线的字符串。例如:
-rwxr-x```
以下是这些字母和符号的含义:
位置 | 含义 |
1 | 文件类型:- = 文件,d = 目录,l = 符号链接,p = 命名管道,c = 字符设备,b = 块设备 |
2–4 | 文件所有者的读取、写入和执行权限 |
5–7 | 文件组的读取、写入和执行权限 |
8–10 | 所有其他用户的读取、写入和执行权限 |
所以我们的示例-rwxr-x
表示一个文件,该文件可以被所有者读取、写入和执行,可以被组读取和执行,并且不能被其他用户访问
推荐阅读
你好,我是拾叁,7年开发老司机、互联网两年外企5年。怼得过阿三老美,也被PR comments搞崩溃过。这些年我打过工,创过业,接过私活,也混过upwork。赚过钱也亏过钱。一路过来,给我最深的感受就是不管学什么,一定要不断学习。只要你能坚持下来,就很容易实现弯道超车!所以,不要问我现在干什么是否来得及。如果你还没什么方向,可以先关注我,这里会经常分享一些前沿资讯和编程知识,帮你积累弯道超车的资本。